





import re
from collections import defaultdict
from typing import Callable, Dict, Any, Optional, List, Tuple

class MockRequest:
    def __init__(self, method: str = "GET", path: str = "/", headers: dict = None):
        self.method = method.upper()
        self.path = path
        self.headers = headers or {}
        self.path_params = {}

class MockResponse:
    def __init__(self, body: Any = None, status_code: int = 200, headers: dict = None):
        self.body = body
        self.status_code = status_code
        self.headers = headers or {}

class Route:
    def __init__(self, path: str, endpoint: Callable, methods: List[str]):
        self.path_pattern = path
        self.endpoint = endpoint
        self.methods = [m.upper() for m in methods]
        
        # 转换路径为匹配正则表达式
        pattern = re.sub(r"{(\w+)}", r"(?P<\1>[^/]+)", path)
        self.regex = re.compile(f"^{pattern}$")
    
    def match(self, request: MockRequest) -> Optional[Dict[str, str]]:
        """检查请求路径是否匹配路由，返回路径参数字典或None"""
        match = self.regex.match(request.path)
        return match.groupdict() if match else None

class Router:
    def __init__(self):
        self.routes: List[Route] = []
        self.middlewares = []
    
    def add_route(self, path: str, endpoint: Callable, methods: List[str]):
        """添加新路由到路由器"""
        self.routes.append(Route(path, endpoint, methods))
    
    # 添加便捷的HTTP方法装饰器
    def get(self, path: str):
        return lambda func: self.add_route(path, func, ["GET"])
    
    def post(self, path: str):
        return lambda func: self.add_route(path, func, ["POST"])
    
    def put(self, path: str):
        return lambda func: self.add_route(path, func, ["PUT"])
    
    def delete(self, path: str):
        return lambda func: self.add_route(path, func, ["DELETE"])
    
    def add_middleware(self, middleware: Callable):
        """添加中间件处理函数"""
        self.middlewares.append(middleware)
    
    def _apply_middlewares(self, request: MockRequest, endpoint: Callable):
        """应用中间件链"""
        # 创建一个处理响应栈
        def dispatch(request, current_endpoint):
            if not self.middlewares:
                return current_endpoint
            
            # 创建一个中间件链
            async def next_middleware(request):
                # 获取下一个中间件（如果存在）
                if self.middlewares:
                    mw = self.middlewares.pop(0)
                    return await mw(request, lambda: next_middleware(request))
                else:
                    return await current_endpoint(request)
            
            return next_middleware(request)
        
        return dispatch(request, endpoint)
    
    async def handle_request(self, request: MockRequest) -> MockResponse:
        """处理传入请求并返回响应"""
        # 查找匹配的路由
        for route in self.routes:
            if path_params := route.match(request):
                # 检查HTTP方法是否允许
                if request.method not in route.methods:
                    return MockResponse(
                        f"Method {request.method} not allowed", 
                        405,
                        {"Allow": ", ".join(route.methods)}
                    )
                
                # 设置路径参数
                request.path_params = path_params
                
                # 应用中间件
                endpoint = route.endpoint
                if self.middlewares:
                    endpoint = self._apply_middlewares(request, endpoint)
                
                # 执行路由处理函数
                try:
                    response = await endpoint(request, **path_params)
                    if isinstance(response, tuple):
                        body, status = response
                        return MockResponse(body, status)
                    return MockResponse(response)
                except Exception as e:
                    return MockResponse(f"Server error: {str(e)}", 500)
        
        # 没有找到匹配的路由
        return MockResponse("Not Found", 404)

# 示例使用
if __name__ == "__main__":
    # 创建路由器和应用
    router = Router()

    # 模拟中间件
    @router.add_middleware
    async def logging_middleware(request: MockRequest, call_next: Callable):
        print(f"Request received: {request.method} {request.path}")
        response = await call_next()
        print(f"Response sent: {response.status_code}")
        return response

    # 添加路由
    @router.get("/")
    async def home(request: MockRequest):
        return {"message": "Welcome to our API!"}

    @router.get("/users/{user_id}")
    async def get_user(request: MockRequest, user_id: int):
        return {
            "user_id": user_id,
            "name": "John Doe",
            "request_path": request.path
        }

    @router.post("/items")
    async def create_item(request: MockRequest):
        # 实际应用中会解析请求体
        return {"action": "item created", "status": "success"}, 201

    # 模拟请求处理
    async def handle_request_example():
        # 有效请求
        req1 = MockRequest("GET", "/")
        res1 = await router.handle_request(req1)
        print(f"\nResponse 1: {res1.status_code} {res1.body}")

        # 带路径参数的请求
        req2 = MockRequest("GET", "/users/123")
        res2 = await router.handle_request(req2)
        print(f"\nResponse 2: {res2.status_code} {res2.body}")

        # POST请求
        req3 = MockRequest("POST", "/items")
        res3 = await router.handle_request(req3)
        print(f"\nResponse 3: {res3.status_code} {res3.body}")

        # 不存在的路由
        req4 = MockRequest("GET", "/not_found")
        res4 = await router.handle_request(req4)
        print(f"\nResponse 4: {res4.status_code} {res4.body}")

        # 方法不允许
        req5 = MockRequest("POST", "/users/123")
        res5 = await router.handle_request(req5)
        print(f"\nResponse 5: {res5.status_code} {res5.body}")

    import asyncio
    asyncio.run(handle_request_example())



    